<?php
/**
 * DBERP 进销存系统
 *
 * ==========================================================================
 * @link      http://www.dberp.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   http://www.dberp.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Sales\Repository;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Sales\Entity\SalesSendOrder;
use Sales\Entity\SalesSendWarehouseGoods;

class SalesSendOrderRepository extends EntityRepository
{
    /**
     * 发货订单sql
     * @param array $search
     * @return \Doctrine\ORM\Query
     */
    public function findAllSendOrder(array $search = []): \Doctrine\ORM\Query
    {
        $query = $this->getEntityManager()->createQueryBuilder()
            ->select('s', 'o')
            ->from(SalesSendOrder::class, 's')
            ->join('s.oneSalesOrder', 'o')
            ->orderBy('s.sendOrderId', 'DESC');

        if (!empty($search['sales_goods_sn'])) {
            $query->andWhere($query->expr()->in('s.sendOrderId', $this->getEntityManager()->createQueryBuilder()
                ->select('g.sendOrderId')->from(SalesSendWarehouseGoods::class, 'g')
                ->where($query->expr()->like('g.goodsSerialNumberStr', "'%".$search['sales_goods_sn']."%'"))
                ->getDQL()));
        }

        $query = $this->querySearchData($search, $query);

        return $query->getQuery();
    }

    /**
     * 获取最大发货单id
     * @return float|int|mixed|string
     * @throws \Doctrine\ORM\NoResultException
     * @throws \Doctrine\ORM\NonUniqueResultException
     */
    public function getMaxSendOrderId()
    {
        $query = $this->getEntityManager()->createQueryBuilder();
        $query->select('MAX(s.sendOrderId) as maxSendOrderId')->from(SalesSendOrder::class, 's');

        $maxId = $query->getQuery()->getSingleScalarResult();

        return $maxId == null ? 1 : $maxId + 1;
    }

    private function querySearchData($search, QueryBuilder $queryBuilder): QueryBuilder
    {
        if(isset($search['start_amount']) && $search['start_amount'] > 0)   $queryBuilder->andWhere($queryBuilder->expr()->gte('o.salesOrderAmount', $search['start_amount']));
        if(isset($search['end_amount']) && $search['end_amount'] > 0)       $queryBuilder->andWhere($queryBuilder->expr()->lte('o.salesOrderAmount', $search['end_amount']));
        if(!empty($search['send_order_sn']))                                $queryBuilder->andWhere($queryBuilder->expr()->like('s.sendOrderSn', "'%".$search['send_order_sn']."%'"));
        if(!empty($search['customer_contacts']))                            $queryBuilder->andWhere($queryBuilder->expr()->like('o.customerContacts', "'%".$search['customer_contacts']."%'"));
        if(!empty($search['customer_phone']))                               $queryBuilder->andWhere($queryBuilder->expr()->like('o.customerPhone', "'%".$search['customer_phone']."%'"));
        if(isset($search['customer_id']) && $search['customer_id'] > 0)     $queryBuilder->andWhere($queryBuilder->expr()->eq('o.customerId', $search['customer_id']));
        if(!empty($search['receivables_code']))                             $queryBuilder->andWhere($queryBuilder->expr()->eq('o.receivablesCode', ':code'))->setParameter('code', $search['receivables_code']);
        if(isset($search['sales_order_state']) && is_numeric($search['sales_order_state'])) $queryBuilder->andWhere($queryBuilder->expr()->eq('o.salesOrderState', $search['sales_order_state']));
        if(isset($search['return_state']) && is_numeric($search['return_state']))           $queryBuilder->andWhere($queryBuilder->expr()->eq('s.returnState', $search['return_state']));

        $timeFiled = self::checkOrderTimeType($search);
        if(!empty($search['start_time']))       $queryBuilder->andWhere($queryBuilder->expr()->gte($timeFiled, ':startTime'))->setParameter('startTime', strtotime($search['start_time'].' 00:00:00'));
        if(!empty($search['end_time']))         $queryBuilder->andWhere($queryBuilder->expr()->lte($timeFiled, ':endTime'))->setParameter('endTime', strtotime($search['end_time'].' 23:59:59'));

        return $queryBuilder;
    }

    private static function checkOrderTimeType($search): string
    {
        if (!isset($search['time_type']) || !$search['time_type']) return 'o.receivingTime';

        $timeFiled = 'o.receivingTime';
        if ($search['time_type'] == 6) $timeFiled = 'o.shippingTime';

        return $timeFiled;
    }
}